package com.xuelang.pipeline.domain.resource.service.impl;

import cn.hutool.core.lang.Assert;
import com.xuelang.pipeline.client.common.exception.BizException;
import com.xuelang.pipeline.domain.resource.GitOperation;
import com.xuelang.pipeline.domain.resource.service.GitDomainService;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.internal.storage.file.FileRepository;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
import org.springframework.stereotype.Service;

import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * @author liuyuan.ly
 * @since 2024/6/17 10:15
 */
@Service
@Slf4j
public class GitDomainServiceImpl implements GitDomainService {
    @Override
    public GitOperation getRemoteBranchList(GitOperation gitOperation) {
        Assert.notNull(gitOperation.getCodeRepository(), "代码仓库不能为空");
        Assert.notNull(gitOperation.getUsername(), "代码仓库用户名不能为空");
        Assert.notNull(gitOperation.getPassword(), "代码仓库密码不能为空");
        Collection<Ref> call = null;
        try {
            call = Git.lsRemoteRepository()
                    .setRemote(gitOperation.getCodeRepository())
                    .setCredentialsProvider(new UsernamePasswordCredentialsProvider
                            (gitOperation.getUsername(), gitOperation.getPassword()))
                    .call();
        } catch (GitAPIException e) {
            log.error("请检查git凭证权限，获取远程分支信息错误", e);
            throw new BizException("请检查git凭证权限，获取远程分支信息错误");
        } catch (Exception e) {
            log.error("获取远程分支信息失败，请检代码仓库地址及git凭证token是否准确", e);
            throw new BizException("获取远程分支信息失败，请检代码仓库地址及git凭证token是否准确");
        }
        List<String> remoteRefList = new ArrayList<>();
        for (Ref ref : call) {
            String refName = ref.getName();
            if (refName.startsWith("refs/heads/")) {                       //需要进行筛选
                String branchName = refName.replace("refs/heads/", "");
                remoteRefList.add(branchName);
            }
        }
        GitOperation gitResp = new GitOperation();
        gitResp.setRemoteList(remoteRefList);
        return gitResp;
    }

    @Override
    public GitOperation checkGitClientWithBranchName(GitOperation operation) {
        Assert.notNull(operation.getCodeRepository(), "代码仓库不能为空");
        Assert.notNull(operation.getUsername(), "代码仓库用户名不能为空");
        Assert.notNull(operation.getPassword(), "代码仓库密码不能为空");
        Assert.notNull(operation.getBranchName(), "代码仓库分支不能为空");
        String path = operation.getPath();

        File file = new File(path);
        Repository repo = null;
        try {
            if (!file.exists()) {
                path = path.replace("/.git", "");
                Git.cloneRepository()
                        .setURI(operation.getCodeRepository())
                        .setDirectory(new File(path))
                        .setBranch(operation.getBranchName())
                        .setCredentialsProvider(new UsernamePasswordCredentialsProvider(operation.getUsername(), operation.getPassword()))
                        .call();
            } else {
                repo = new FileRepository(new File(path));
                Git git = new Git(repo);
                git.pull()
                        .setCredentialsProvider(new UsernamePasswordCredentialsProvider(operation.getUsername(), operation.getPassword()))
                        .call();
            }
        } catch (Exception e) {
            log.error("初始化git客户端拉取代码失败", e);
            throw new RuntimeException(e);
        } finally {
            if (repo != null) {
                repo.close();
            }
        }
        return operation;

    }
}
